#include "local_msg.h"
#include "local_mqtt.h"
#include "sys_log.h"
#include "thread_msg.h"
#include "cJSON.h"
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

/**
 * Msg info release
 */
int local_msg_app_info_pub(points_info_t* info)
{
    struct timeval tv;
    char new_topic[200];
    char* newpayload = NULL;
    cJSON *cjson_root, *cjson_apps, *cjson_apps_item, *cjson_app, *cjson_points, *cjson_point;

    cjson_root = cJSON_CreateObject();
    if (NULL == cjson_root)
        return -1;
    cJSON_AddNumberToObject(cjson_root, "tick", 1);
    gettimeofday(&tv, NULL);
    cJSON_AddNumberToObject(cjson_root, "time", tv.tv_sec);
    cJSON_AddStringToObject(cjson_root, "src", "sys_manager");
    cjson_app = cJSON_CreateObject();
    cJSON_AddItemToObject(cjson_root, "app", cjson_app);
    cjson_apps = cJSON_CreateArray();
    cJSON_AddItemToObject(cjson_app, "apps", cjson_apps);
    cjson_apps_item = cJSON_CreateObject();

    cjson_points = cJSON_CreateArray();
    cJSON_AddItemToObject(cjson_apps_item, "points", cjson_points);
    for (int i = 0; i < info->cnt; i++) {
        cjson_point = cJSON_CreateObject();
        cJSON_AddStringToObject(cjson_point, "key", info->key_list+i);
        cJSON_AddStringToObject(cjson_point, "val", info->val_list+i);
        cJSON_AddItemToObject(cjson_points, "NULL", cjson_point);
    }

    newpayload = cJSON_PrintUnformatted(cjson_root);
    if (newpayload == NULL) {
        sys_log_erro("malloc error\n");
        cJSON_Delete(cjson_root);
        return -1;
    }

    snprintf(new_topic, 200, "%s%s%s", MQ_APP, "/sys_manager", MQ_INFO_APP);
    local_mqtt_pub(new_topic, newpayload);

    cJSON_free(newpayload);
    cJSON_Delete(cjson_root);
    return 0;
}

/**
 * Msg write release
 */
int local_msg_app_read_pub(char* app_name)
{
    struct timeval tv;
    char new_topic[200];
    char* newpayload = NULL;
    cJSON *cjson_root, *cjson_apps, *cjson_apps_item, *cjson_app, *cjson_points, *cjson_point;

    cjson_root = cJSON_CreateObject();
    if (NULL == cjson_root)
        return -1;
    cJSON_AddNumberToObject(cjson_root, "tick", 1);
    gettimeofday(&tv, NULL);
    cJSON_AddNumberToObject(cjson_root, "time", tv.tv_sec);
    cJSON_AddStringToObject(cjson_root, "src", "sys_manager");
    cjson_app = cJSON_CreateObject();
    cJSON_AddItemToObject(cjson_root, "app", cjson_app);
    cjson_apps = cJSON_CreateArray();
    cJSON_AddItemToObject(cjson_app, "apps", cjson_apps);
    cjson_apps_item = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_apps_item, "name", app_name);
    cJSON_AddItemToObject(cjson_apps, "NULL", cjson_apps_item);

    cjson_points = cJSON_CreateArray();
    cJSON_AddItemToObject(cjson_apps_item, "points", cjson_points);
    cjson_point = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_point, "key", "log");
    cJSON_AddItemToObject(cjson_points, "NULL", cjson_point);
    cjson_point = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_point, "key", "version");
    cJSON_AddItemToObject(cjson_points, "NULL", cjson_point);
    cjson_point = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_point, "key", "date");
    cJSON_AddItemToObject(cjson_points, "NULL", cjson_point);

    newpayload = cJSON_PrintUnformatted(cjson_root);
    if (newpayload == NULL) {
        sys_log_erro("malloc error\n");
        cJSON_Delete(cjson_root);
        return -1;
    }

    snprintf(new_topic, 200, "%s%s%s", MQ_APP, "/sys_manager", MQ_INFO_APP);
    local_mqtt_pub(new_topic, newpayload);

    cJSON_free(newpayload);
    cJSON_Delete(cjson_root);
    return 0;
}

int local_mqtt_app_init(char* name)
{
    char topic[100];
    points_info_t* info;

    snprintf(topic, 100, "%s%s%s", MQ_APP, name, MQ_RACK_APP);
    local_mqtt_sub(topic);

    local_msg_app_read_pub(name);
    return 0;
}

/**
 * Handles threads that receive local app ack messages
 */
int local_msg_recv_app_rack(char* topic, char* payload)
{
    int ret = 0;
    return ret;
}

/**
 * Handles threads that receive local app messages
 */
void pthread_local_msg_recv_app_rack(void* param)
{
    msg_t msg;
    while (1) {
        memset(&msg, 0, sizeof(msg_t));
        thread_msg_recv(&msg, MSG_ID_MQ_APP_RACK);
        if (strstr(msg.topic, MQ_RACK_APP) != NULL) {
            local_msg_recv_app_rack(msg.topic, msg.payload);
        }
        if (msg.topic) {
            free(msg.topic);
        }
        if (msg.payload) {
            free(msg.payload);
        }
    }
}

int local_msg_init(void)
{
    int ret = -1;
    pthread_t thread_id_local_recv_app_rack;

    ret = pthread_create(&thread_id_local_recv_app_rack, NULL, pthread_local_msg_recv_app_rack, NULL);
    if (ret < 0) {
        sys_log_erro("local msg pthread create fail\n");
        return -1;
    }
    return 0;
}
